package com.qingyun.material.utils;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.Date;
import java.util.UUID;

/**
 * 文件上传工具类
 */
@Component
public class FileUploadUtil {

    // 文件上传配置常量
    private static final String BASE_UPLOAD_PATH = "D:/QingYunEduSystem/EduSysteam/uploads/";
    private static final long MAX_FILE_SIZE = 50 * 1024 * 1024; // 50MB
    private static final String[] ALLOWED_FILE_TYPES = {
        ".pdf", ".doc", ".docx", ".ppt", ".pptx", 
        ".xls", ".xlsx", ".txt", ".zip", ".rar"
    };

    /**
     * 上传文件到本地服务器
     * @param file 上传的文件
     * @return 存储的文件路径（相对路径，便于存入数据库）
     * @throws IOException 文件操作异常
     */
    public String uploadFile(MultipartFile file) throws IOException {
        // 1. 验证文件是否为空
        if (file.isEmpty()) {
            throw new IllegalArgumentException("上传文件不能为空");
        }

        // 2. 验证文件大小
        if (file.getSize() > MAX_FILE_SIZE) {
            throw new IllegalArgumentException("文件大小不能超过" + (MAX_FILE_SIZE / 1024 / 1024) + "MB");
        }

        // 3. 获取原始文件名和扩展名
        String originalFileName = file.getOriginalFilename();
        if (originalFileName == null || originalFileName.trim().isEmpty()) {
            throw new IllegalArgumentException("文件名不能为空");
        }
        
        String fileExtension = "";
        if (originalFileName.contains(".")) {
            fileExtension = originalFileName.substring(originalFileName.lastIndexOf(".")).toLowerCase();
        }

        // 4. 验证文件类型
        if (!isAllowedFileType(fileExtension)) {
            throw new IllegalArgumentException("不支持的文件类型：" + fileExtension);
        }

        // 5. 生成唯一文件名（避免重复）
        String uniqueFileName = UUID.randomUUID().toString() + fileExtension;

        // 6. 创建存储目录（按日期分目录，便于管理）
        String dateDir = DateUtil.format(new Date(), "yyyyMMdd");
        String fullDirPath = BASE_UPLOAD_PATH + dateDir;
        Path dirPath = Paths.get(fullDirPath);
        if (!Files.exists(dirPath)) {
            Files.createDirectories(dirPath);
        }

        // 7. 保存文件到本地
        String fullFilePath = fullDirPath + "/" + uniqueFileName;
        File targetFile = new File(fullFilePath);
        file.transferTo(targetFile);

        // 8. 返回相对路径（存储到数据库，便于后续读取）
        return dateDir + "/" + uniqueFileName;
    }

    /**
     * 检查文件类型是否允许
     * @param fileExtension 文件扩展名
     * @return 是否允许
     */
    private boolean isAllowedFileType(String fileExtension) {
        if (StrUtil.isBlank(fileExtension)) {
            return false;
        }
        return Arrays.asList(ALLOWED_FILE_TYPES).contains(fileExtension.toLowerCase());
    }

    /**
     * 获取完整的文件路径
     * @param relativePath 相对路径
     * @return 完整路径
     */
    public String getFullPath(String relativePath) {
        return BASE_UPLOAD_PATH + relativePath;
    }

    /**
     * 检查文件是否存在
     * @param relativePath 相对路径
     * @return 是否存在
     */
    public boolean fileExists(String relativePath) {
        if (relativePath == null || relativePath.trim().isEmpty()) {
            return false;
        }
        File file = new File(BASE_UPLOAD_PATH + relativePath);
        return file.exists() && file.isFile();
    }

    /**
     * 删除文件
     * @param relativePath 相对路径
     * @return 是否删除成功
     */
    public boolean deleteFile(String relativePath) {
        if (relativePath == null || relativePath.trim().isEmpty()) {
            return false;
        }
        File file = new File(BASE_UPLOAD_PATH + relativePath);
        if (file.exists() && file.isFile()) {
            return file.delete();
        }
        return false;
    }

    /**
     * 获取上传根路径
     * @return 上传根路径
     */
    public String getBasePath() {
        return BASE_UPLOAD_PATH;
    }

    /**
     * 获取最大文件大小
     * @return 最大文件大小（字节）
     */
    public long getMaxFileSize() {
        return MAX_FILE_SIZE;
    }

    /**
     * 获取允许的文件类型
     * @return 允许的文件类型数组
     */
    public String[] getAllowedFileTypes() {
        return ALLOWED_FILE_TYPES.clone();
    }
}
